import logging

from django import template
from django.core.cache import cache
from django.conf import settings

from browsertests.useragents.models import Useragent
from browsertests.results.models import Result

log = logging.getLogger(__name__)
register = template.Library()

def _get_ordered_uas():
    if "ordered_uas" in cache:
        return cache.get("ordered_uas")
    log.debug("Computing ordered_uas list.")

    ordered_uas = []
    for product, branch, platform in settings.UA_COLUMNS:
        ordered_uas.append(Useragent.objects.get_by_pbp(product, branch,
                                                        platform))

    cache.set("ordered_uas", ordered_uas)
    return ordered_uas

@register.inclusion_tag('tests/teststable.html')
def show_tests(test_list, show_test_links=True):
    ordered_uas = _get_ordered_uas()

    # XXX some of the logic here may belong to the model classes.
    test_ids = [test.id for test in test_list]
    test_to_ua_result = {}
    # XXX Using "in" here with a large number of test identifiers is less than
    # optimal, but it should be better than iterating over the tests
    # and doing a query for each to get the results.
    # The right approach would be to do only one query joining tests and results.
    for result in Result.objects.select_related().filter(test__in=test_ids):
        if not result.test_id in test_to_ua_result:
            test_to_ua_result[result.test_id] = {}
        ua_to_result = test_to_ua_result[result.test_id]
        if result.ua_id in ua_to_result:
            existing = ua_to_result[result.ua_id]
            assert existing.test_version != result.test_version, \
                    "Duplicate results with the same version?"
            # Keep only the most recent results.
            if existing.test_version > result.test_id:
                continue
        ua_to_result[result.ua_id] = result

    for test in test_list:
        ua_to_result = test_to_ua_result.get(test.id, {})
        test.ordered_results = [ua_to_result.get(ua.pk, None) for ua in ordered_uas]

    return {
        'ordered_uas': ordered_uas,
        'test_list': test_list,
        'show_test_links': show_test_links,
    }

@register.inclusion_tag('tests/teststable.html')
def show_test(test):
    return show_tests([test], False)
